Skip to content

Add a guard for huge bounds in bounds propagation#1390

Open
hlinsen wants to merge 8 commits into
NVIDIA:mainfrom
hlinsen:add-bound-prop-check
Open

Add a guard for huge bounds in bounds propagation#1390
hlinsen wants to merge 8 commits into
NVIDIA:mainfrom
hlinsen:add-bound-prop-check

Conversation

@hlinsen

@hlinsen hlinsen commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Semi-continuous var with big-M reformulations can create large row activities where the true residual is
smaller than double precision at that scale.

    row activity      = -2.476e26
    var contribution  = -2.476e26
    true residual     = -2.0e10
    double ULP there  =  3.44e10

  After cancellation:
    computed residual = -3.44e10
    coeff             = -1.23
    candidate bound   =  2.8e10

In that case, floating point cancellation can produce an unsafe candidate bound and later false infeasibility.

We add an usual guard on huge bounds derived. Note that it does not protect against the float cancellation error.

A full cancellation-aware guard would require tracking row activity scale or using compensated activity arithmetic, which would add extra reductions/storage or broader propagation changes.

@hlinsen hlinsen requested a review from a team as a code owner June 4, 2026 03:18
@hlinsen hlinsen added the bug Something isn't working label Jun 4, 2026
@hlinsen hlinsen requested a review from akifcorduk June 4, 2026 03:18
@hlinsen hlinsen added the non-breaking Introduces a non-breaking change label Jun 4, 2026
@hlinsen hlinsen requested a review from nguidotti June 4, 2026 03:18
@copy-pr-bot

copy-pr-bot Bot commented Jun 4, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 30e483b9-c5a2-4c25-95be-91c20798bbe1

📥 Commits

Reviewing files that changed from the base of the PR and between 6d7a941 and 65f9e35.

📒 Files selected for processing (1)
  • cpp/src/mip_heuristics/solve.cu
🚧 Files skipped from review as they are similar to previous changes (1)
  • cpp/src/mip_heuristics/solve.cu

📝 Walkthrough

Walkthrough

Adds a per-update candidate_bound_scale stored in bounds update data, a device predicate that gates candidate bound writes using a scaled absolute-tolerance check, wires the scale from presolve/multi-probe, and adds solver-setting validation for those tolerances.

Changes

Bound Update Validation

Layer / File(s) Summary
Bounds update data shape and view
cpp/src/mip_heuristics/presolve/bounds_update_data.cuh, cpp/src/mip_heuristics/presolve/bounds_update_data.cu
Added candidate_bound_scale to bounds_update_data_t and its view_t; constructor initializes the field and view() exposes it.
Tolerance check predicate
cpp/src/mip_heuristics/presolve/bounds_update_helpers.cuh
New device function accept_candidate_bound_update(bound, abs_tol, candidate_bound_scale) that accepts a candidate when abs(bound) * candidate_bound_scale <= abs_tol.
Conditional bound updates in presolve
cpp/src/mip_heuristics/presolve/bounds_update_helpers.cuh, cpp/src/mip_heuristics/presolve/bounds_presolve.cu, cpp/src/mip_heuristics/presolve/multi_probe.cu
update_bounds_per_cnst now computes new_lb/new_ub and writes them into bnd only when accept_candidate_bound_update accepts each; presolve and multi-probe set candidate_bound_scale = pb.tolerances.absolute_tolerance / context.settings.semi_continuous_big_m.
Solver settings validation
cpp/src/mip_heuristics/solve.cu
Added cuopt_expects in solve_mip_helper validating finiteness/non-negativity of tolerances.absolute_tolerance and that semi_continuous_big_m is finite and greater than absolute_tolerance.

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add a guard for huge bounds in bounds propagation' directly and specifically describes the main change: introducing a guard mechanism to handle large/huge bounds during bounds propagation.
Description check ✅ Passed The description provides detailed context about the problem (floating-point cancellation with semi-continuous variables and big-M reformulations), illustrative examples, and explains the solution (adding a guard on huge bounds).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cpp/src/mip_heuristics/presolve/bounds_update_helpers.cuh`:
- Around line 46-47: The hardcoded acceptance scale (candidate_bound_scale =
f_t{1e-14}) in bounds_update_helpers.cuh makes bound gating inflexible; change
the code to derive this scale from the solver's configured tolerances (or accept
a passed-in relative tolerance) instead of the magic constant: replace the
literal with a parameter or a value read from the solver settings (e.g.,
solver_tolerances.relative_bound_tol or an added function parameter rel_tol) and
use that derived value in the existing comparison that uses
candidate_bound_scale, while keeping the existing variables bound and abs_tol
intact.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f63805a4-c0d7-438e-9fec-93725704b9f2

📥 Commits

Reviewing files that changed from the base of the PR and between d6d6f9e and b148a3b.

📒 Files selected for processing (1)
  • cpp/src/mip_heuristics/presolve/bounds_update_helpers.cuh

Comment thread cpp/src/mip_heuristics/presolve/bounds_update_helpers.cuh Outdated
@hlinsen

hlinsen commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test b4ba3b1

@hlinsen

hlinsen commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 4c513aa

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cpp/src/mip_heuristics/presolve/bounds_presolve.cu`:
- Around line 121-122: The division computing upd.candidate_bound_scale
(pb.tolerances.absolute_tolerance / context.settings.semi_continuous_big_m) must
be guarded against zero or near-zero denominators; modify the code that sets
upd.candidate_bound_scale to first check context.settings.semi_continuous_big_m
> epsilon (use a small constant like 1e-12 or an existing solver epsilon if
available) and if not, set candidate_bound_scale to a safe clamped value (e.g.
absolute_tolerance / epsilon or a predefined max_scale) so the acceptance
predicate does not get disabled by Inf/huge values; update any related comments
and consider validating semi_continuous_big_m at solver initialization as an
alternative.

In `@cpp/src/mip_heuristics/presolve/multi_probe.cu`:
- Around line 144-147: The division for upd_0.candidate_bound_scale and
upd_1.candidate_bound_scale uses context.settings.semi_continuous_big_m without
guarding against zero/near-zero; update the assignment logic (where
candidate_bound_scale is set for upd_0 and upd_1) to first check that
context.settings.semi_continuous_big_m > epsilon (choose a small epsilon, e.g.
1e-12) and only perform pb.tolerances.absolute_tolerance / semi_continuous_big_m
when that condition holds, otherwise set candidate_bound_scale to a safe
fallback or clamp the computed value into a reasonable range (max_scale) to
avoid infinity/huge values that break the acceptance predicate; reference the
variables upd_0, upd_1, candidate_bound_scale, pb.tolerances.absolute_tolerance,
and context.settings.semi_continuous_big_m when making the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 7382ad84-9366-4f1e-89c5-9962d8c2e87b

📥 Commits

Reviewing files that changed from the base of the PR and between b148a3b and 4c513aa.

📒 Files selected for processing (5)
  • cpp/src/mip_heuristics/presolve/bounds_presolve.cu
  • cpp/src/mip_heuristics/presolve/bounds_update_data.cu
  • cpp/src/mip_heuristics/presolve/bounds_update_data.cuh
  • cpp/src/mip_heuristics/presolve/bounds_update_helpers.cuh
  • cpp/src/mip_heuristics/presolve/multi_probe.cu
✅ Files skipped from review due to trivial changes (1)
  • cpp/src/mip_heuristics/presolve/bounds_update_data.cuh

Comment thread cpp/src/mip_heuristics/presolve/bounds_presolve.cu
Comment thread cpp/src/mip_heuristics/presolve/multi_probe.cu
@hlinsen

hlinsen commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 2d0e086

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cpp/src/mip_heuristics/solve.cu`:
- Around line 339-346: The validation currently allows
settings.tolerances.absolute_tolerance == 0 which disables the huge-bound guard;
change the cuopt_expects condition in the existing validation call to require
absolute_tolerance > f_t(0) (strictly positive) instead of >= f_t(0), and update
the error message text in the same cuopt_expects invocation to state that
mip_absolute_tolerance must be strictly positive (finite and > 0) while keeping
the existing checks for settings.semi_continuous_big_m > mip_absolute_tolerance;
this affects the cuopt_expects invocation that references
settings.tolerances.absolute_tolerance and settings.semi_continuous_big_m.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 895b072f-8592-4012-aebf-3feb7b2b610f

📥 Commits

Reviewing files that changed from the base of the PR and between 2d0e086 and 6d7a941.

📒 Files selected for processing (3)
  • cpp/src/mip_heuristics/presolve/bounds_presolve.cu
  • cpp/src/mip_heuristics/presolve/multi_probe.cu
  • cpp/src/mip_heuristics/solve.cu

Comment thread cpp/src/mip_heuristics/solve.cu
@hlinsen

hlinsen commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 94dbc1a

@hlinsen

hlinsen commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 65f9e35

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working non-breaking Introduces a non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants